home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termMarker.c < prev    next >
C/C++ Source or Header  |  1995-07-04  |  19KB  |  844 lines

  1. /*
  2. **    termMarker.c
  3. **
  4. **    Text block marker routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* BM_Draw():
  13.      *
  14.      *    Redraw or remove marked regions.
  15.      */
  16.  
  17. VOID __regargs
  18. BM_Draw(struct BlockMarker *Marker,VOID (*Select)(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height))
  19. {
  20.         /* Is the first line the same as the last line? If so,
  21.          * continue and mark only single characters. Else,
  22.          * determine first line and column to mark and last
  23.          * line and last column.
  24.          */
  25.  
  26.     if(Marker -> FirstLine != Marker -> LastLine)
  27.     {
  28.         LONG    First    = Marker -> FirstLine - Marker -> Top,
  29.             Last    = Marker -> LastLine  - Marker -> Top,
  30.             Lines;
  31.  
  32.             /* Is the first line visible? If so, mark it. */
  33.  
  34.         if(First >= 0)
  35.             (*Select)(Marker,Marker -> FirstColumn,First,Marker -> Width - Marker -> FirstColumn,1);
  36.         else
  37.         {
  38.             (*Select)(Marker,0,0,Marker -> Width,1);
  39.  
  40.             First = 0;
  41.         }
  42.  
  43.             /* Is the last line visible? If so, mark it. */
  44.  
  45.         if(Last >= 0 && Last < Marker -> Height)
  46.             (*Select)(Marker,0,Last,Marker -> LastColumn,1);
  47.         else
  48.             Last = Marker -> Height;
  49.  
  50.             /* Determine the number of lines the selection spans. */
  51.  
  52.         if((Lines = Last - First - 1) > 0)
  53.             (*Select)(Marker,0,First + 1,Marker -> Width,Lines);
  54.     }
  55.     else
  56.     {
  57.             /* Is the first column different from the last column? */
  58.  
  59.         if(Marker -> FirstColumn != Marker -> LastColumn)
  60.         {
  61.                 /* Is the line visible? If so, mark it. */
  62.  
  63.             if(Marker -> Top <= Marker -> LastLine && Marker -> LastLine < Marker -> Top + Marker -> Height)
  64.                 (*Select)(Marker,Marker -> FirstColumn,Marker -> FirstLine - Marker -> Top,Marker -> LastColumn - Marker -> FirstColumn,1);
  65.         }
  66.     }
  67. }
  68.  
  69.     /* BM_ClearMark(struct BlockMarker *Marker):
  70.      *
  71.      *    Free block marker memory.
  72.      */
  73.  
  74. VOID __regargs
  75. BM_ClearMark(struct BlockMarker *Marker)
  76. {
  77.     BM_Draw(Marker,Marker -> Unselect);
  78.  
  79.     FreeVecPooled(Marker);
  80. }
  81.  
  82.     /* BM_SetMark():
  83.      *
  84.      *    Create block marker structure.
  85.      */
  86.  
  87. struct BlockMarker * __regargs
  88. BM_SetMark(APTR Object,VPTR Select,VPTR Unselect,LONG Width,LONG Height,LONG LeftEdge,LONG TopEdge,LONG Top,LONG Lines,LONG X,LONG Y,WORD TextFontWidth,WORD TextFontHeight)
  89. {
  90.     if(Height && Lines)
  91.     {
  92.         struct BlockMarker *Marker;
  93.  
  94.             /* Allocate marker buffer. */
  95.  
  96.         if(Marker = (struct BlockMarker *)AllocVecPooled(sizeof(struct BlockMarker),MEMF_ANY | MEMF_CLEAR))
  97.         {
  98.                 /* Fill in the object or canvas, usually a RastPort. */
  99.  
  100.             Marker -> Object    = Object;
  101.  
  102.                 /* Fill in the canvas left and top edge. */
  103.  
  104.             Marker -> LeftEdge    = LeftEdge;
  105.             Marker -> TopEdge    = TopEdge;
  106.  
  107.                 /* Fill in the select and unselect routines. */
  108.  
  109.             Marker -> Select    = Select;
  110.             Marker -> Unselect    = Unselect;
  111.  
  112.                 /* Fill in current display window top and number of
  113.                  * lines in the buffer.
  114.                  */
  115.  
  116.             Marker -> Top        = Top;
  117.             Marker -> Lines        = Lines;
  118.  
  119.                 /* Fill in width and height of the display window. */
  120.  
  121.             Marker -> Width        = Width;
  122.             Marker -> Height    = Height;
  123.  
  124.                 /* Fill in the marker anchor point. */
  125.  
  126.             Marker -> FirstColumn    = X;
  127.             Marker -> LastColumn    = X;
  128.             Marker -> FirstLine    = Y + Top;
  129.             Marker -> LastLine    = Y + Top;
  130.  
  131.                 /* Fill in current mouse position. */
  132.  
  133.             Marker -> LastX        = X;
  134.             Marker -> LastY        = Y;
  135.  
  136.             Marker -> OriginX    = X;
  137.             Marker -> OriginY    = Y + Top;
  138.  
  139.                 /* Remember text font dimensions. */
  140.  
  141.             Marker -> TextFontWidth    = TextFontWidth;
  142.             Marker -> TextFontHeight= TextFontHeight;
  143.  
  144.             Marker -> WriteMask    = ((struct RastPort *)Object) -> Mask;
  145.         }
  146.  
  147.             /* Return marker buffer. */
  148.  
  149.         return(Marker);
  150.     }
  151.     else
  152.         return(NULL);
  153. }
  154.  
  155.     /* BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta):
  156.      *
  157.      *    Extend current block marker. This routine was
  158.      *    first written by me, but Martin Berndt rewrote it
  159.      *    after we both realised that it would not work
  160.      *    properly.
  161.      */
  162.  
  163. VOID __regargs
  164. BM_ExtendMark(struct BlockMarker *Marker,LONG X,LONG Y,LONG Delta)
  165. {
  166.     if(Marker -> LastX != X || Marker -> LastY != Y)
  167.     {
  168.         LONG    OldCharPos,NewCharPos,
  169.             CharStart,CharEnd,
  170.             CharOrigin,
  171.             OriginY,
  172.             Lines;
  173.         BYTE    Crossed;
  174.  
  175.         OriginY = Marker -> OriginY - Marker -> Top;
  176.  
  177.             /* Deal with illegal X position. */
  178.  
  179.         if(X < 0)
  180.             X = 0;
  181.  
  182.         if(X > Marker -> Width)
  183.             X = Marker -> Width;
  184.  
  185.             /* Deal with illegal Y position. */
  186.  
  187.         if(Y < 0)
  188.             Y = 0;
  189.  
  190.         if(Y >= Marker -> Height)
  191.             Y = Marker -> Height - 1;
  192.  
  193.         if(Y + Marker -> Top >= Marker -> Lines)
  194.             Y = Marker -> Lines - Marker -> Top - 1;
  195.  
  196.             /* Is the Y position larger than the last line? If so,
  197.              * truncate it.
  198.              */
  199.  
  200.         if(Y > Marker -> Lines - Marker -> Top)
  201.             Y -= Marker -> Lines - Marker -> Top;
  202.  
  203.             /* Select the text. */
  204.  
  205.         OldCharPos    = (Marker -> LastY + Marker -> Top) * Marker -> Width + Marker -> LastX;
  206.         NewCharPos    = (Y + Marker -> Top) * Marker -> Width + X;
  207.  
  208.         CharStart    = Marker -> FirstLine * Marker -> Width + Marker -> FirstColumn;
  209.         CharEnd        = Marker -> LastLine * Marker -> Width + Marker -> LastColumn;
  210.  
  211.         CharOrigin    = Marker -> OriginY * Marker -> Width + Marker -> OriginX;
  212.  
  213.         Crossed        = (OldCharPos < CharOrigin) ^ (NewCharPos < CharOrigin);
  214.  
  215.         if(NewCharPos > OldCharPos)
  216.         {
  217.             if(Delta && Y < OriginY)
  218.                 (*Marker -> Select)(Marker,0,Y,Marker -> Width,1);
  219.  
  220.             if(Crossed)
  221.             {
  222.                 if((Lines = OriginY - Marker -> LastY - 1) >= 0)
  223.                 {
  224.                     (*Marker -> Unselect)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  225.  
  226.                     if(Lines > 0)
  227.                         (*Marker -> Unselect)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  228.  
  229.                     if(Marker -> OriginX)
  230.                         (*Marker -> Unselect)(Marker,0,OriginY,Marker -> OriginX,1);
  231.                 }
  232.                 else
  233.                 {
  234.                     if(Delta)
  235.                         (*Marker -> Unselect)(Marker,0,OriginY,Marker -> LastX,1);
  236.                     else
  237.                         (*Marker -> Unselect)(Marker,Marker -> LastX,OriginY,Marker -> OriginX - Marker -> LastX,1);
  238.                 }
  239.  
  240.                 Marker -> FirstColumn    = Marker -> OriginX;
  241.                 Marker -> FirstLine     = Marker -> OriginY;
  242.  
  243.                 Marker -> LastX        = Marker -> OriginX;
  244.                 Marker -> LastY        = OriginY;
  245.             }
  246.             else
  247.             {
  248.                 if(OldCharPos < CharOrigin)
  249.                 {
  250.                     if((Lines = Y - Marker -> LastY - 1) >= 0)
  251.                     {
  252.                         (*Marker -> Unselect)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  253.  
  254.                         if(Lines > 0)
  255.                             (*Marker -> Unselect)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  256.  
  257.                         (*Marker -> Unselect)(Marker,0,Y,X,1);
  258.                     }
  259.                     else
  260.                     {
  261.                         if(Delta)
  262.                             (*Marker -> Unselect)(Marker,0,Y,X,1);
  263.                         else
  264.                             (*Marker -> Unselect)(Marker,Marker -> LastX,Y,X - Marker -> LastX,1);
  265.                     }
  266.  
  267.                     Marker -> FirstColumn    = X;
  268.                     Marker -> FirstLine    = Y + Marker -> Top;
  269.                 }
  270.             }
  271.  
  272.             if(NewCharPos > CharEnd)
  273.             {
  274.                 if((Lines = Y - Marker -> LastY - 1) >= 0)
  275.                 {
  276.                     (*Marker -> Select)(Marker,Marker -> LastX,Marker -> LastY,Marker -> Width - Marker -> LastX,1);
  277.  
  278.                     if(Lines > 0)
  279.                         (*Marker -> Select)(Marker,0,Marker -> LastY + 1,Marker -> Width,Lines);
  280.  
  281.                     (*Marker -> Select)(Marker,0,Y,X,1);
  282.                 }
  283.                 else
  284.                 {
  285.                     if(Delta)
  286.                         (*Marker -> Select)(Marker,0,Y,X,1);
  287.                     else
  288.                         (*Marker -> Select)(Marker,Marker -> LastX,Y,X - Marker -> LastX,1);
  289.                 }
  290.  
  291.                 Marker -> LastColumn    = X;
  292.                 Marker -> LastLine    = Y + Marker -> Top;
  293.             }
  294.         }
  295.         else
  296.         {
  297.             if(Delta && Y > OriginY)
  298.                 (*Marker -> Select)(Marker,0,Y,Marker -> Width,1);
  299.  
  300.             if(Crossed)
  301.             {
  302.                 if((Lines = Marker -> LastY - OriginY - 1) >= 0)
  303.                 {
  304.                     (*Marker -> Unselect)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  305.  
  306.                     if(Lines > 0)
  307.                         (*Marker -> Unselect)(Marker,0,OriginY + 1,Marker -> Width,Lines);
  308.  
  309.                     (*Marker -> Unselect)(Marker,Marker -> OriginX,OriginY,Marker -> Width - Marker -> OriginX,1);
  310.                 }
  311.                 else
  312.                 {
  313.                     if(Delta)
  314.                         (*Marker -> Unselect)(Marker,Marker -> LastX,OriginY,Marker -> Width - Marker -> LastX,1);
  315.                     else
  316.                         (*Marker -> Unselect)(Marker,Marker -> OriginX,OriginY,Marker -> LastX - Marker -> OriginX,1);
  317.                 }
  318.  
  319.                 Marker -> LastColumn    = Marker -> OriginX;
  320.                 Marker -> LastLine    = Marker -> OriginY;
  321.  
  322.                 Marker -> LastX        = Marker -> OriginX;
  323.                 Marker -> LastY        = OriginY;
  324.             }
  325.             else
  326.             {
  327.                 if(OldCharPos > CharOrigin)
  328.                 {
  329.                     if((Lines = Marker -> LastY - Y - 1) >= 0)
  330.                     {
  331.                         if(Marker -> LastX)
  332.                             (*Marker -> Unselect)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  333.  
  334.                         if(Lines > 0)
  335.                             (*Marker -> Unselect)(Marker,0,Y + 1,Marker -> Width,Lines);
  336.  
  337.                         (*Marker -> Unselect)(Marker,X,Y,Marker -> Width - X,1);
  338.                     }
  339.                     else
  340.                     {
  341.                         if(Delta)
  342.                             (*Marker -> Unselect)(Marker,X,Y,Marker -> Width - X,1);
  343.                         else
  344.                             (*Marker -> Unselect)(Marker,X,Y,Marker -> LastX - X,1);
  345.                     }
  346.  
  347.                     Marker -> LastColumn    = X;
  348.                     Marker -> LastLine    = Y + Marker -> Top;
  349.                 }
  350.             }
  351.  
  352.             if(NewCharPos < CharStart)
  353.             {
  354.                 if((Lines = Marker -> LastY - Y - 1) >= 0)
  355.                 {
  356.                     if(Marker -> LastX)
  357.                         (*Marker -> Select)(Marker,0,Marker -> LastY,Marker -> LastX,1);
  358.  
  359.                     if(Lines > 0)
  360.                         (*Marker -> Select)(Marker,0,Y + 1,Marker -> Width,Lines);
  361.  
  362.                     (*Marker -> Select)(Marker,X,Y,Marker -> Width - X,1);
  363.                 }
  364.                 else
  365.                 {
  366.                     if(Delta)
  367.                         (*Marker -> Select)(Marker,X,Y,Marker -> Width - X,1);
  368.                     else
  369.                         (*Marker -> Select)(Marker,X,Y,Marker -> LastX - X,1);
  370.                 }
  371.  
  372.                 Marker -> FirstColumn    = X;
  373.                 Marker -> FirstLine    = Y + Marker -> Top;
  374.             }
  375.         }
  376.  
  377.         Marker -> LastX = X;
  378.         Marker -> LastY = Y;
  379.     }
  380. }
  381.  
  382.  
  383.     /* ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height):
  384.      *
  385.      *    Toggle selection subroutine.
  386.      */
  387.  
  388. VOID
  389. ToggleSelect(struct BlockMarker *Marker,LONG Left,LONG Top,LONG Width,LONG Height)
  390. {
  391.     struct RastPort *RPort = (struct RastPort *)Marker -> Object;
  392.  
  393.     if(Width && Height)
  394.     {
  395.         UWORD    OldAPen    = ReadAPen(RPort),
  396.             OldBPen    = ReadBPen(RPort),
  397.             OldDrMd    = ReadDrMd(RPort),
  398.             Mask;
  399.  
  400.         Left    = Marker -> LeftEdge + Left * Marker -> TextFontWidth;
  401.         Top    = Marker -> TopEdge + Top * Marker -> TextFontHeight;
  402.  
  403.         if(Kick30)
  404.         {
  405.             Mask = (1L << GetBitMapAttr(RPort -> BitMap,BMA_DEPTH)) - 1;
  406.  
  407.             SetABPenDrMd(RPort,Mask,OldBPen,JAM1 | COMPLEMENT);
  408.  
  409.             RectFill(RPort,Left,Top,Left + Width * Marker -> TextFontWidth - 1,Top + Height * Marker -> TextFontHeight - 1);
  410.  
  411.             SetABPenDrMd(RPort,OldAPen,OldBPen,OldDrMd);
  412.         }
  413.         else
  414.         {
  415.             Mask = (1L << RPort -> BitMap -> Depth) - 1;
  416.  
  417.             SetAPen(RPort,Mask);
  418.             SetDrMd(RPort,JAM1 | COMPLEMENT);
  419.  
  420.             RectFill(RPort,Left,Top,Left + Width * Marker -> TextFontWidth - 1,Top + Height * Marker -> TextFontHeight - 1);
  421.  
  422.             SetAPen(RPort,OldAPen);
  423.             SetDrMd(RPort,OldDrMd);
  424.         }
  425.     }
  426. }
  427.  
  428.     /* WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len,BOOL NeedClipConversion):
  429.      *
  430.      *    Write a string to the clipboard, sans trailing spaces.
  431.      */
  432.  
  433. VOID __regargs
  434. WriteTrimmedString(struct IFFHandle *Handle,STRPTR String,LONG Len,BOOL NeedClipConversion)
  435. {
  436.     while(Len > 0 && String[Len - 1] == ' ')
  437.         Len--;
  438.  
  439.     if(Len)
  440.     {
  441.         if(NeedClipConversion)
  442.         {
  443.             UBYTE    Buffer[256];
  444.             LONG    Size,i;
  445.             STRPTR    Dest;
  446.             UBYTE    c;
  447.  
  448.             do
  449.             {
  450.                 Size = MIN(Len,256);
  451.  
  452.                 Len -= Size;
  453.  
  454.                 for(i = 0, Dest = Buffer ; i < Size ; i++)
  455.                 {
  456.                     if(c = ISOConversion[*String++])
  457.                         *Dest++ = c;
  458.                     else
  459.                         *Dest++ = ' ';
  460.                 }
  461.  
  462.                 if(Dest > Buffer)
  463.                 {
  464.                     Size = (ULONG)Dest - (ULONG)&Buffer[0];
  465.  
  466.                     while(Size > 0 && Buffer[Size - 1] == ' ')
  467.                         Size--;
  468.  
  469.                     if(Size > 0)
  470.                         WriteChunkBytes(Handle,Buffer,Size);
  471.                 }
  472.             }
  473.             while(Len > 0);
  474.         }
  475.         else
  476.             WriteChunkBytes(Handle,String,Len);
  477.     }
  478. }
  479.  
  480.     /* ClipPage(struct BlockMarker *Marker,BOOL Append,BOOL NeedClipConversion):
  481.      *
  482.      *    Send the entire marked page to the clipboard.
  483.      */
  484.  
  485. STATIC VOID __inline
  486. ClipPage(struct BlockMarker *Marker,BOOL Append,BOOL NeedClipConversion)
  487. {
  488.     struct IFFHandle    *Handle;
  489.     APTR             Buffer;
  490.     LONG             Size;
  491.  
  492.     if(Append)
  493.         GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Buffer,&Size);
  494.     else
  495.     {
  496.         Buffer    = NULL;
  497.         Size    = 0;
  498.     }
  499.  
  500.     if(Handle = AllocIFF())
  501.     {
  502.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  503.         {
  504.             InitIFFasClip(Handle);
  505.  
  506.             if(!OpenIFF(Handle,IFFF_WRITE))
  507.             {
  508.                 if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  509.                 {
  510.                     if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  511.                     {
  512.                         LONG    Lines = Marker -> LastLine - Marker -> FirstLine - 1,
  513.                             i;
  514.  
  515.                         if(Buffer)
  516.                         {
  517.                             WriteChunkBytes(Handle,Buffer,Size);
  518.  
  519.                             FreeVecPooled(Buffer);
  520.                         }
  521.  
  522.                         WriteTrimmedString(Handle,&Raster[RasterWidth * Marker -> FirstLine + Marker -> FirstColumn],Marker -> Width - Marker -> FirstColumn,NeedClipConversion);
  523.                         WriteChunkBytes(Handle,"\n",1);
  524.  
  525.                         if(Lines > 0)
  526.                         {
  527.                             STRPTR Line = &Raster[(Marker -> FirstLine + 1) * RasterWidth];
  528.  
  529.                             for(i = 0 ; i < Lines ; i++)
  530.                             {
  531.                                 WriteTrimmedString(Handle,Line,Marker -> Width,NeedClipConversion);
  532.                                 WriteChunkBytes(Handle,"\n",1);
  533.  
  534.                                 Line += RasterWidth;
  535.                             }
  536.                         }
  537.  
  538.                         WriteTrimmedString(Handle,&Raster[RasterWidth * Marker -> LastLine],Marker -> LastColumn,NeedClipConversion);
  539.                         WriteChunkBytes(Handle,"\n",1);
  540.  
  541.                         PopChunk(Handle);
  542.                     }
  543.  
  544.                     PopChunk(Handle);
  545.                 }
  546.  
  547.                 CloseIFF(Handle);
  548.             }
  549.  
  550.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  551.         }
  552.  
  553.         FreeIFF(Handle);
  554.     }
  555. }
  556.  
  557.     /* MarkWord(LONG MouseX,LONG MouseY):
  558.      *
  559.      *    Mark a single word on the main screen (double-click).
  560.      */
  561.  
  562. VOID __regargs
  563. MarkWord(LONG MouseX,LONG MouseY)
  564. {
  565.     LONG FirstX,FirstY;
  566.  
  567.     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  568.     FirstY = MouseY / TextFontHeight;
  569.  
  570.     if(FirstX > LastPrintableColumn)
  571.         FirstX = LastPrintableColumn;
  572.  
  573.     if(FirstY > LastLine)
  574.         FirstY = LastLine;
  575.  
  576.     ObtainSemaphore(RasterSemaphore);
  577.  
  578.     if(Raster[FirstY * RasterWidth + FirstX] != ' ' && Raster[FirstY * RasterWidth + FirstX])
  579.     {
  580.         STRPTR    Line = &Raster[FirstY * RasterWidth];
  581.         LONG    LastX;
  582.  
  583.         LastX = FirstX;
  584.  
  585.         while(FirstX > 0 && Line[FirstX - 1] != ' ')
  586.             FirstX--;
  587.  
  588.         while(LastX < LastPrintableColumn && Line[LastX + 1] != ' ')
  589.             LastX++;
  590.  
  591.         ObtainSemaphore(&TerminalSemaphore);
  592.  
  593.         if(WindowMarker = BM_SetMark(Window -> RPort,ToggleSelect,ToggleSelect,LastPrintableColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,(TextFontWidth * CharCellNominator) / CharCellDenominator,TextFontHeight))
  594.         {
  595.             SetMask(RPort,DepthMask);
  596.  
  597.             Marking = TRUE;
  598.  
  599.             ReportMouse(TRUE,Window);
  600.  
  601.             BM_ExtendMark(WindowMarker,LastX + 1,FirstY,0);
  602.  
  603.             SetClipMenu(TRUE);
  604.         }
  605.  
  606.         ReleaseSemaphore(&TerminalSemaphore);
  607.     }
  608.  
  609.     ReleaseSemaphore(RasterSemaphore);
  610. }
  611.  
  612.     /* SetMarker(LONG MouseX,LONG MouseY):
  613.      *
  614.      *    Anchor a marker to the current mouse position.
  615.      */
  616.  
  617. VOID __regargs
  618. SetMarker(LONG MouseX,LONG MouseY)
  619. {
  620.     LONG FirstX,FirstY;
  621.  
  622.     FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  623.     FirstY = MouseY / TextFontHeight;
  624.  
  625.     if(FirstX > LastPrintableColumn)
  626.         FirstX = LastPrintableColumn;
  627.  
  628.     if(FirstY > LastLine)
  629.         FirstY = LastLine;
  630.  
  631.     ObtainSemaphore(&TerminalSemaphore);
  632.  
  633.     if(WindowMarker = BM_SetMark(Window -> RPort,ToggleSelect,ToggleSelect,LastPrintableColumn + 1,LastLine + 1,WindowLeft,WindowTop,0,LastLine + 1,FirstX,FirstY,(TextFontWidth * CharCellNominator) / CharCellDenominator,TextFontHeight))
  634.     {
  635.         SetMask(RPort,DepthMask);
  636.  
  637.         Marking = TRUE;
  638.  
  639.         ReportMouse(TRUE,Window);
  640.  
  641.         SetClipMenu(TRUE);
  642.     }
  643.  
  644.     ReleaseSemaphore(&TerminalSemaphore);
  645. }
  646.  
  647.     /* MoveMarker(LONG MouseX,LONG MouseY):
  648.      *
  649.      *    Move the marker with the mouse.
  650.      */
  651.  
  652. VOID __regargs
  653. MoveMarker(LONG MouseX,LONG MouseY)
  654. {
  655.     if(WindowMarker)
  656.     {
  657.         ULONG EffectiveWidth;
  658.  
  659.         ObtainSemaphore(&TerminalSemaphore);
  660.  
  661.         EffectiveWidth = (TextFontWidth * CharCellNominator) / CharCellDenominator;
  662.  
  663.         BM_ExtendMark(WindowMarker,(MouseX + EffectiveWidth - 1) / EffectiveWidth,MouseY / TextFontHeight,0);
  664.  
  665.         ReleaseSemaphore(&TerminalSemaphore);
  666.     }
  667. }
  668.  
  669.     /* DropMarker():
  670.      *
  671.      *    Drop the window marker, restore the window contents.
  672.      */
  673.  
  674. VOID
  675. DropMarker()
  676. {
  677.     if(WindowMarker)
  678.     {
  679.         struct RastPort    *RPort    = WindowMarker -> Object;
  680.         UBYTE         Mask    = WindowMarker -> WriteMask;
  681.  
  682.         ObtainSemaphore(&TerminalSemaphore);
  683.  
  684.         BM_ClearMark(WindowMarker);
  685.  
  686.         ReleaseSemaphore(&TerminalSemaphore);
  687.  
  688.         SetMask(RPort,Mask);
  689.  
  690.         ReportMouse(FALSE,Window);
  691.  
  692.         WindowMarker = NULL;
  693.  
  694.         Marking = FALSE;
  695.  
  696.         SetClipMenu(FALSE);
  697.     }
  698. }
  699.  
  700.     /* FreeMarker():
  701.      *
  702.      *    Free the main window marker.
  703.      */
  704.  
  705. VOID
  706. FreeMarker()
  707. {
  708.     if(WindowMarker)
  709.     {
  710.         struct RastPort    *RPort    = WindowMarker -> Object;
  711.         UBYTE         Mask    = WindowMarker -> WriteMask;
  712.  
  713.         FreeVecPooled(WindowMarker);
  714.  
  715.         WindowMarker = NULL;
  716.  
  717.         SetMask(RPort,Mask);
  718.  
  719.         ReportMouse(FALSE,Window);
  720.  
  721.         Marking = FALSE;
  722.  
  723.         SetClipMenu(FALSE);
  724.     }
  725. }
  726.  
  727.     /* ClipMarker(BYTE Append):
  728.      *
  729.      *    Transfer the marked area to the clipboard.
  730.      */
  731.  
  732. VOID __regargs
  733. ClipMarker(BYTE Append)
  734. {
  735.     if(WindowMarker)
  736.     {
  737.         ObtainSemaphore(RasterSemaphore);
  738.  
  739.         SetWait(Window);
  740.  
  741.         if(WindowMarker -> FirstColumn == WindowMarker -> Width)
  742.         {
  743.             WindowMarker -> FirstLine++;
  744.  
  745.             WindowMarker -> FirstColumn = 0;
  746.         }
  747.  
  748.         if(WindowMarker -> LastColumn == 0)
  749.         {
  750.             WindowMarker -> LastLine--;
  751.  
  752.             WindowMarker -> LastColumn = WindowMarker -> Width;
  753.         }
  754.  
  755.         if(WindowMarker -> FirstLine <= WindowMarker -> LastLine)
  756.         {
  757.             if(WindowMarker -> FirstLine != WindowMarker -> LastLine || WindowMarker -> FirstColumn != WindowMarker -> LastColumn)
  758.             {
  759.                 if(WindowMarker -> FirstLine == WindowMarker -> LastLine)
  760.                 {
  761.                     if(Config -> TerminalConfig -> FontMode != FONT_STANDARD)
  762.                     {
  763.                         UBYTE    Buffer[256];
  764.                         LONG    Len,i;
  765.                         STRPTR    Dest,
  766.                             Source    = &Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn];
  767.                         LONG    Size    = WindowMarker -> LastColumn - WindowMarker -> FirstColumn;
  768.                         UBYTE    c;
  769.  
  770.                         if(Append)
  771.                         {
  772.                             do
  773.                             {
  774.                                 Len = MIN(Size,256);
  775.  
  776.                                 Size -= Len;
  777.  
  778.                                 for(i = 0, Dest = Buffer ; i < Len ; i++)
  779.                                 {
  780.                                     if(c = ISOConversion[*Source++])
  781.                                         *Dest++ = c;
  782.                                     else
  783.                                         *Dest++ = ' ';
  784.                                 }
  785.  
  786.                                 if(Dest > Buffer)
  787.                                     AddClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  788.                             }
  789.                             while(Size > 0);
  790.                         }
  791.                         else
  792.                         {
  793.                             BOOL FirstWrite = TRUE;
  794.  
  795.                             do
  796.                             {
  797.                                 Len = MIN(Size,256);
  798.  
  799.                                 Size -= Len;
  800.  
  801.                                 for(i = 0, Dest = Buffer ; i < Len ; i++)
  802.                                 {
  803.                                     if(c = ISOConversion[*Source++])
  804.                                         *Dest++ = c;
  805.                                     else
  806.                                         *Dest++ = ' ';
  807.                                 }
  808.  
  809.                                 if(Dest > Buffer)
  810.                                 {
  811.                                     if(FirstWrite)
  812.                                     {
  813.                                         FirstWrite = FALSE;
  814.  
  815.                                         SaveClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  816.                                     }
  817.                                     else
  818.                                         AddClip(Buffer,(ULONG)Dest - (ULONG)&Buffer[0]);
  819.                                 }
  820.                             }
  821.                             while(Size > 0);
  822.                         }
  823.                     }
  824.                     else
  825.                     {
  826.                         if(Append)
  827.                             AddClip(&Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn],WindowMarker -> LastColumn - WindowMarker -> FirstColumn);
  828.                         else
  829.                             SaveClip(&Raster[RasterWidth * WindowMarker -> FirstLine + WindowMarker -> FirstColumn],WindowMarker -> LastColumn - WindowMarker -> FirstColumn);
  830.                     }
  831.                 }
  832.                 else
  833.                     ClipPage(WindowMarker,Append,Config -> TerminalConfig -> FontMode != FONT_STANDARD);
  834.             }
  835.         }
  836.  
  837.         ClrWait(Window);
  838.  
  839.         ReleaseSemaphore(RasterSemaphore);
  840.  
  841.         DropMarker();
  842.     }
  843. }
  844.